--==============================
--[[ 兔子血buff相关函数 ]]
--==============================
local function IsLifeDrainable(target)
    return not target:HasAnyTag(NON_LIFEFORM_TARGET_TAGS) or target:HasTag("lifedrainable")
end

local function rabbit_blood(owner, data)
    -- 生命吸取
    if owner.components.health and owner.components.health:IsHurt() and IsLifeDrainable(data.target) then
        owner.components.health:DoDelta(5, false, "buff_furry_cola_chicken_wings")
    end
end

--==============================
--[[ 蔷薇拿铁buff相关函数 ]]
--==============================
local function OnTickRosyLatte(inst, target)
    if target.components.health ~= nil and
        not target.components.health:IsDead() and
        not target:HasTag("playerghost") then
        target.components.health:DoDelta(1, nil, "nuts_buff_rosy_latte")
    else
        inst.components.debuff:Stop()
    end
end

--==============================
--[[ 看见一弯银轮buff相关函数 ]]
--==============================
local PLANTS_RANGE = 1
local MAX_PLANTS = 18
local PLANTFX_TAGS = { "wormwood_plant_fx" }
local function PlantTick(food, inst)
    if inst.sg:HasStateTag("ghostbuild") or inst.components.health:IsDead() or not inst.entity:IsVisible() then
        return
    end
    if inst:GetCurrentPlatform() ~= nil then
        return
    end
    local x, y, z = inst.Transform:GetWorldPosition()
    if #TheSim:FindEntities(x, y, z, PLANTS_RANGE, PLANTFX_TAGS) < MAX_PLANTS then
        local map = TheWorld.Map
        local pt = Vector3(0, 0, 0)
        local offset = FindValidPositionByFan(
            math.random() * 2 * PI,
            math.random() * PLANTS_RANGE,
            3,
            function(offset)
                pt.x = x + offset.x
                pt.z = z + offset.z
                return map:CanPlantAtPoint(pt.x, 0, pt.z)
                    and #TheSim:FindEntities(pt.x, 0, pt.z, .5, PLANTFX_TAGS) < 3
                    and map:IsDeployPointClear(pt, nil, .5)
                    and not map:IsPointNearHole(pt, .4)
            end
        )
        if offset ~= nil then
            local plant = SpawnPrefab("wormwood_plant_fx")
            plant.Transform:SetPosition(x + offset.x, 0, z + offset.z)
            local rnd = math.random()
            rnd = table.remove(inst.plantpool_nuts,
                math.clamp(math.ceil(rnd * rnd * #inst.plantpool_nuts), 1, #inst.plantpool_nuts))
            table.insert(inst.plantpool_nuts, rnd)
            plant:SetVariation(rnd)
        end
    end
end
local PLANT_TAGS = { "tendable_farmplant" }
local function TendToPlantsAOE(food, inst)
    local x, y, z = inst.Transform:GetWorldPosition()
    for _, v in pairs(TheSim:FindEntities(x, y, z, TUNING.WORMWOOD_BLOOM_FARM_PLANT_INTERACT_RANGE, PLANT_TAGS)) do
        if v.components.farmplanttendable ~= nil then
            v.components.farmplanttendable:TendTo(inst)
        end
    end
end

--==============================
--[[ 超级香甜粘玉米buff相关函数 ]]
--==============================
local function OnWontEatFood(inst, data)
    if inst.components.talker ~= nil then
        inst.components.talker:Say(GetString(inst, "ANNOUNCE_EAT", "STICKY_CORN"))
    end
end

local buffs = {
    -- 不断回响的时光
    echotime = {
        duration = 360,
        priority = 2,
        onattachedfn = function(inst, target)
            if target.components.locomotor then
                target.components.locomotor:SetExternalSpeedMultiplier(inst, "nuts_buff_echotime", 1.2)
            end
        end,
        ondetachedfn = function(inst, target)
            if target.components.locomotor then
                target.components.locomotor:RemoveExternalSpeedMultiplier(inst, "nuts_buff_echotime")
            end
        end,
    },
    -- 于火光中映照出来
    flameborn = {
        duration = 480,
        priority = 1,
        onattachedfn = function(inst, target)
            if target.components.grogginess ~= nil then
                target.components.grogginess:AddResistanceSource(inst, TUNING.SLEEPRESISTBUFF_VALUE)
            end
            if target.prefab == "wuyi_lambris" then
                if target.components.moistureimmunity == nil then
                    target:AddComponent("moistureimmunity")
                end
                target.components.moistureimmunity:AddSource(inst)
                if target.components.freezable and target.components.freezable.redirectfn == nil then
                    target.components.freezable.redirectfn = function() return true end
                    target.flameborn = true -- 防止其他mod也给该人物上redirectfn函数，但是这个概率很低，可忽略不计
                end
            end
        end,
        ondetachedfn = function(inst, target)
            if target.components.grogginess ~= nil then
                target.components.grogginess:RemoveResistanceSource(inst)
            end
            if target.prefab == "wuyi_lambris" then
                if target.components.moistureimmunity ~= nil then
                    target.components.moistureimmunity:RemoveSource(inst)
                end
                if target.components.freezable and target.flameborn then
                    target.components.freezable.redirectfn = nil
                    target.flameborn = nil
                end
            end
        end,
    },
    -- 回忆里,在此处
    memorybound = {
        duration = 480,
        priority = 1,
        onattachedfn = function(inst, target)
            if target.components.grogginess ~= nil then
                target.components.grogginess:AddResistanceSource(inst, TUNING.SLEEPRESISTBUFF_VALUE)
            end
            if target.prefab == "rhine" then
                target.components.planardamage:AddBonus(inst, 20, "nuts_buff_memorybound")
            end
        end,
        ondetachedfn = function(inst, target)
            if target.components.grogginess ~= nil then
                target.components.grogginess:RemoveResistanceSource(inst)
            end
            if target.prefab == "rhine" then
                target.components.planardamage:RemoveBonus(inst, "nuts_buff_memorybound")
            end
        end,
    },
    -- 兔子血
    rabbit_blood = {
        duration = 480,
        priority = 1,
        onattachedfn = function(inst, target)
            if target.components.combat ~= nil then
                target.components.combat.externaldamagemultipliers:SetModifier(inst, 1.25)
            end
            if target.prefab == "gallop" then
                target:ListenForEvent("onhitother", rabbit_blood)
            end
        end,
        ondetachedfn = function(inst, target)
            if target.components.combat ~= nil then
                target.components.combat.externaldamagemultipliers:RemoveModifier(inst)
            end
            if target.prefab == "gallop" then
                target:RemoveEventCallback("onhitother", rabbit_blood)
            end
        end,
    },
    -- 蔷薇拿铁(加速8分钟)
    rosy_latte = {
        duration = 480,
        priority = 2,
        onattachedfn = function(inst, target)
            if target.components.locomotor then
                target.components.locomotor:SetExternalSpeedMultiplier(inst, "nuts_buff_rosy_latte", 1.2)
            end
        end,
        ondetachedfn = function(inst, target)
            if target.components.locomotor then
                target.components.locomotor:RemoveExternalSpeedMultiplier(inst, "nuts_buff_rosy_latte")
            end
        end,
    },
    -- 蔷薇拿铁(回血30秒)
    rosy_latte1 = {
        duration = 30,
        priority = 1,
        onattachedfn = function(inst, target)
            inst.task = inst:DoPeriodicTask(1, OnTickRosyLatte, nil, target)
        end,
        onextendedfn = function(inst, target)
            inst.components.timer:StopTimer("buffover")
            inst.components.timer:StartTimer("buffover", 30)
            inst.task:Cancel()
            inst.task = inst:DoPeriodicTask(1, OnTickRosyLatte, nil, target)
        end,
        ondetachedfn = function(inst, target)
            inst:Remove()
        end,
    },
    -- 看见一弯银轮
    silver_crescent = {
        duration = 480,
        priority = 1,
        onattachedfn = function(inst, target)
            target.plantpool_nuts = { 1, 2, 3, 4 }
            for i = # target.plantpool_nuts, 1, -1 do
                table.insert(target.plantpool_nuts, table.remove(target.plantpool_nuts, math.random(i)))
            end
            if inst.planttask == nil then
                inst.planttask = inst:DoPeriodicTask(.25, PlantTick, nil, target)
            end
            if inst.tendplanttask == nil then
                inst.tendplanttask = inst:DoPeriodicTask(.5, TendToPlantsAOE, nil, target)
            end
        end,
        ondetachedfn = function(inst, target)
            target.plantpool_nuts = nil
            inst:Remove()
        end,
    },
    -- 松香脆肠卷
    pine_sausage_roll = {
        duration = 480,
        priority = 1,
        onattachedfn = function(inst, target)
            target:AddTag("notarget")
        end,
        ondetachedfn = function(inst, target)
            target:RemoveTag("notarget")
        end,
    },
    -- 开心果拿铁(加速8分钟)
    pistachio_latte = {
        duration = 480,
        priority = 2,
        onattachedfn = function(inst, target)
            if target.components.locomotor then
                target.components.locomotor:SetExternalSpeedMultiplier(inst, "nuts_buff_pistachio_latte", 1.2)
            end
        end,
        ondetachedfn = function(inst, target)
            if target.components.locomotor then
                target.components.locomotor:RemoveExternalSpeedMultiplier(inst, "nuts_buff_pistachio_latte")
            end
        end,
    },
    -- 开心果拿铁(防御4分钟)
    pistachio_latte1 = {
        duration = 240,
        priority = 1,
        onattachedfn = function(inst, target)
            if target.components.health then
                target.components.health.externalabsorbmodifiers:SetModifier(inst, TUNING.BUFF_PLAYERABSORPTION_MODIFIER)
            end
        end,
        ondetachedfn = function(inst, target)
            if target.components.health then
                target.components.health.externalabsorbmodifiers:RemoveModifier(inst)
            end
        end,
    },
    -- 超级香甜粘玉米(4分钟)
    sticky_corn = {
        duration = 240,
        priority = 2,
        onattachedfn = function(inst, target)
            target:ListenForEvent("wonteatfood", OnWontEatFood)
            if target.components.health then
                target.components.health:DoDelta(-20, nil, "nuts_buff_sticky_corn", nil, inst, true)
            end
            local item = SpawnPrefab("boneshard")
            if item.Physics ~= nil then
                item.Physics:Teleport(target.Transform:GetWorldPosition())
            else
                item.Transform:SetPosition(target.Transform:GetWorldPosition())
            end
            item.components.inventoryitem:OnDropped(true, .5)
        end,
        ondetachedfn = function(inst, target)
            target:RemoveEventCallback("wonteatfood", OnWontEatFood)
        end,
    },
}

return buffs
